﻿<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>SignalR 测试</title>
</head>
<body>
    <script src="./signalr.js"></script>
    <script>
        // https://www.tutorialspoint.com/how-to-create-guid-uuid-in-javascript
        function createUUID() {
            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
                return v.toString(16);
            });
        }

        let id = createUUID();
        let groupId = "group-2022";
        let intervalNo = -1;

        // 链接到自己的hub 初始化 路由：/custom 被路由节点捕获
        let connection = new signalR.HubConnectionBuilder()
            .withUrl("/custom?deviceId=" + id)
            .build();

        // 开始连接 调用后台 BeginSendData 方法 成功后双方交互数据
        connection.start().then(() => {
            console.log("开始链接");
            connection.send('BeginSendData', { id: id, message: "链接成功了" + new Date() })
            intervalNo = startHeartbeat();
        });

        // 重连方法
        const startSignalRConnection = connection => connection.start()
            .then(() => {
                console.info("重连成功！");
                intervalNo = startHeartbeat();
            })
            .catch(err => {
                console.error('SignalR Connection Error: ', err)
                //alert("即时消息链接已断开，请重新刷新页面")
            });

        // 启动链接
        //async function start() {
        //    try {
        //        await connection.start().then(function () {
        //            startHeartbeat();
        //        }).catch(function (err) {
        //            clearInterval();
        //            return console.error(err.toString());
        //        });
        //        console.log("connected");
        //    } catch (err) {
        //        console.log(err);
        //        setTimeout(() => start(), 5000);
        //    }
        //};

        // 设置超时时间(30分钟超时)
        connection.serverTimeoutInMilliseconds = 30 * 60 * 1000;
        // 超时时间过了之后会自动断开链接
        // 链接断开，尝试重连
        connection.onclose(() => {
            console.error("连接断开");
            clearInterval(intervalNo);
            setTimeout(startSignalRConnection(connection), 5000);
        });

        // 调用 SingleClientCaller 这个方法
        const selfCall = () => {
            //debugger;
            connection.send('SingleClientCaller', { id: id, message: "当前客户端消息" + new Date() });
        };

        // 调用AllClientResponse这个方法
        const allCall = () => {
            //debugger;
            connection.send('AllClientResponse', { id: id, message: "所有客户端消息" + new Date() });
        };

        // 触发后台控制器广播
        const sendData = () => {
            //debugger;
            fetch('/api/CustomHub/SendData');
        };

        // call signalR hub function from client
        const withReturn = () => {
            //debugger;
            connection.invoke('get_date')
                .then(data => console.log('get_date', data));
        };

        // 加入组
        const joinGroup = () => {
            connection.send('JoinGroup', { id: id, groupId: groupId });
        };

        // 离开组
        const leaveGroup = () => {
            connection.send('LeaveGroup', { id: id, groupId: groupId });
        };

        // 发送组消息
        const sendGroupMessage = () => {
            connection.send('SendGroupMessage', { id: id, groupId: groupId, message: "组客户端消息" + new Date() });
        };

        // 发送组消息（排除自己）
        const sendGroupMessageExcludeSelf = () => {
            connection.send('SendGroupMessageExcludeSelf', { id: id, groupId: groupId, message: "组客户端消息（排除自己）" + new Date() });
        };

        // 触发后台控制器组播
        const sendGroupData = () => {
            //debugger;
            fetch('/api/CustomHub/SendGroupData?groupId=' + groupId);
        };

        // 发送组消息
        const heartbeat = () => {
            connection.send('Heartbeat', { message: "心跳消息" + new Date() });
        };

        // 开启心跳
        const startHeartbeat = () => {
            /*intervalNo = setInterval(heartbeat, 1000);*/
            return setInterval(heartbeat, 1000);
        };

        // 清理心跳
        const endHeartbeat = () => {
            clearInterval(intervalNo);
        };

        // 挂断
        const goodbye = () => {
            connection.send('Goodbye').then(() => {
                console.timeLog("挂断成功");
            });
        };

        // 后台默认触发
        connection.on("ClientHook", data => console.log('客户端触发成功', data));

        // 后台指定方法触发之后
        connection.on("client_recive", data => console.log('后台触发成功', data));
    </script>

    <button onclick="selfCall()">当前客户端消息</button>
    <button onclick="allCall()">所有客户端消息</button>
    <button onclick="sendData()">触发后台控制器广播</button>
    <button onclick="withReturn()">包含返回值</button>
    <br />
    <br />
    <button onclick="joinGroup()">加入组</button>
    <button onclick="leaveGroup()">离开组</button>
    <button onclick="sendGroupMessage()">发送组消息</button>
    <button onclick="sendGroupMessageExcludeSelf()">发送组消息（排除自己）</button>
    <button onclick="sendGroupData()">触发后台控制器组播</button>
    <br />
    <br />
    <button onclick="goodbye()">挂断</button>
</body>
</html>

<!-- http://localhost:5260/index.html -->
